#include <iostream>
#include "FileTools.h"
#include <openssl/sha.h> // 哈希加密库  // openssl：开源密码语言库
#include <ctime>
#include "StdMyString.h"

// int main()
// {
//     std::string name = "zhangsan";
//     FileTools::MakeDir("./存档/" + name);
//     FileTools::MakeDir("./存档/" + name + "/存档一");
//     FileTools::MakeDir("./存档/" + name + "/存档二");
//     FileTools::MakeDir("./存档/" + name + "/存档三");
//     // FileTools::RemoveDir("./存档/" + name);

//     return 0;
// }

// 生成随机盐值
std::string Generate()
{
    srand(time(nullptr));
    std::string s;
    s.resize(16); // 16个字节的盐
    for (int i = 0; i < 16; i++)
    {
        // 字符区间：33~126（可见字符 - ' '）
        s[i] = rand() % 94 + 33;
    }
    return s; // 盐值
}

// 哈希加盐
std::pair<std::string, std::string> HashWithSalt(const std::string &passwd)
{
    auto salt = Generate();
    auto TruePasswd = passwd + salt;
    unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
    SHA256((const unsigned char *)TruePasswd.c_str(), TruePasswd.size(), hash);

    std::string s;
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        char temp[3] = {0}; // 两个位置放十六进制，一个放\0
        snprintf(temp, sizeof(temp), "%02x", hash[i]);
        s += temp;
    }
    return {s, salt};
}

// 判断密码是否相等
bool IsPasswdSame(const std::string &passwd, const std::string &salt, const std::string &Hash)
{
    auto TruePasswd = passwd + salt;
    unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
    SHA256((const unsigned char *)TruePasswd.c_str(), TruePasswd.size(), hash);

    std::string s;
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        char temp[3] = {0}; // 两个位置放十六进制，一个放\0
        snprintf(temp, sizeof(temp), "%02x", hash[i]);
        s += temp;
    }

    return s == Hash;
}

int main()
{
#if 0
    // 计算机密码学
    // 明文：直接能看见的有效数据
    // 密文：对明文加密
    std::string userName = "zhangsan";
    std::string passwd = "123456";
    std::vector<std::string> v = {userName+" "+passwd};
    FileTools::AppendLine("./user.txt", v);
#endif

#if 0
    std::string passwd = "123456";
    unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
    SHA256((const unsigned char *)passwd.c_str(), passwd.size(), hash);
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        printf("%x", hash[i]);
    }
    std::cout << std::endl;
#endif

#if 0
    std::string userName = "zhangsan";
    std::string passwd = "123456";
    unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
    SHA256((const unsigned char *)passwd.c_str(), passwd.size(), hash);

    std::string s;
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        char temp[3] = {0}; // 两个位置放十六进制，一个放\0
        snprintf(temp, sizeof(temp), "%02x", hash[i]);
        s += temp;
    }
    std::vector<std::string> v = {userName + " " + s};
    FileTools::AppendLine("./user.txt", v);
#endif

#if 0
    // 哈希加盐
    std::string userName = "zhangsan";
    std::string passwd = "123456";
    auto salt = Generate();
    auto TruePasswd = passwd + salt;
    unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
    SHA256((const unsigned char *)TruePasswd.c_str(), TruePasswd.size(), hash);

    std::string s;
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        char temp[3] = {0}; // 两个位置放十六进制，一个放\0
        snprintf(temp, sizeof(temp), "%02x", hash[i]);
        s += temp;
    }
    std::vector<std::string> v = {userName + " " + s + " " + salt};
    FileTools::AppendLine("./user.txt", v);
#endif

#if 1
    std::string userName = "zhangsan";
    std::string passwd = "123456";

    // 文件读出来
    auto vec = FileTools::ReadLine("./user.txt");
    for (auto &Line : vec)
    {
        StdMyString s(Line.c_str());
        MyStringList l = s.split(" ");
        // std::cout << l << std::endl;
        auto Account = l[0];
        auto Passwd = l[1];
        auto salt = l[2];
        if(Account == userName.c_str() && IsPasswdSame(passwd, salt.c_str(), Passwd.c_str()))
        {
            std::cout << "登陆成功!\n";
        }
    }
#endif

    return 0;
}